package com.klitors.creator;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.AbstractMap;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import com.klitors.creator.utils.CreateUtils;
import com.klitors.creator.utils.FileUtils;

/**
 * @author 66
 * @date 2016年10月16日
 */
public class Properties extends AbstractMap<String, String> {
	public static final String EXECUTE_PATTERN_DEFAULT = "hibernate";
	public static final String EXECUTE_PATTERN_DBUTILS = "dbutils";
	public static final String EXECUTE_PATTERN_HIBERNATE = "hibernate";

	public static final String SOURCE_PATH_DEFAULT = "src";
	public static final String SOURCE_PATH_ECLIPSE = "src";
	public static final String SOURCE_PATH_MAVEN = "src/main/java";

	private Map<String, String> props = new HashMap<>();
	/**
	 * User
	 */
	private String beanName;
	private Class<?> clazz;
	/**
	 * src/cn/itheima
	 */
	private String parentPath;
	/**
	 * src
	 */
	private String sourcePath;

	public Properties(Class<?> clazz) {
		// 参数读取顺序:读取本机配置->读取用户配置->初始化参数
		this.clazz = clazz;
		readFromInnerProps();
		readFromUserProps();
		initParam();
		initProps();
	}

	private void initParam() {
		this.beanName = getParam("bean_name", clazz.getSimpleName());
		this.sourcePath = getParam("source_path", "src");
		this.parentPath = getParam("parent_path", CreateUtils.getParentPath(clazz, sourcePath));
	}

	private String getParam(String paramName, String defaultValue) {
		String str = props.get(paramName);
		return str != null ? str : defaultValue;
	}

	private void initProps() {
		this.putIfNull("parent_path", parentPath);
		this.putIfNull("parent_package", CreateUtils.getParentPackage(clazz));
		this.putIfNull("bean_package", clazz.getPackage().getName());
		this.putIfNull("bean_name", beanName);
		this.putIfNull("full_bean_name", clazz.getName());
		this.putIfNull("lower_name", CreateUtils.firstCharLower(beanName));
		this.putIfNull("date", new SimpleDateFormat("yyyy年MM月dd日").format(new Date()));
		this.putIfNull("id_type", CreateUtils.getIdType(clazz));
		this.putIfNull("bean_path", CreateUtils.getBeanPath(clazz, sourcePath));
		this.putIfNull("id_name", CreateUtils.getIdName(clazz));
		this.putIfNull("source_path", sourcePath);
		this.putIfNull("user", "klitors");
	}

	private void readFromInnerProps() {
		readPropsComm(Properties.class.getResourceAsStream("creator.properties"));
	}

	private void readFromUserProps() {
		InputStream is = clazz.getResourceAsStream("/creator.properties");
		readPropsComm(is);
	}

	private void readPropsComm(InputStream is) {
		if (is == null) {
			return;
		}
		java.util.Properties properties = new java.util.Properties();
		try {
			properties.load(new BufferedReader(new InputStreamReader(is, "UTF-8")));
			Enumeration<?> pns = properties.propertyNames();
			while (pns.hasMoreElements()) {
				String key = (String) pns.nextElement();
				String value = properties.getProperty(key);
				props.put(key, value);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public boolean containsKey(String key) {
		return props.containsKey(key);
	}

	public String get(String key) {
		return props.get(key);
	}

	public String put(String key, String value) {
		return props.put(key, value);
	}

	public String putIfNull(String key, String value) {
		return props.get(key) == null ? props.put(key, value) : props.get(key);
	}

	public String remove(Object key) {
		return props.remove(key);
	}

	public Class<?> getClazz() {
		return clazz;
	}

	@Override
	public Set<Map.Entry<String, String>> entrySet() {
		return props.entrySet();
	}

	public String path_action() {
		return FileUtils.mkPath(parentPath, "web/action");
	}

	public String path_action_java() {
		return FileUtils.mkPath(path_action(), beanName + "Action.java");
	}

	public String path_action_xml() {
		return FileUtils.mkPath(path_action(), beanName + "Action.xml");
	}

	public String path_struts_xml() {
		return FileUtils.mkPath(sourcePath, "struts.xml");
	}

	public String path_interceptor() {
		return FileUtils.mkPath(parentPath, "web/interceptor");

	}

	public String path_parent() {
		return parentPath;
	}

	public String getPackage(String path) {
		path = path.replace("\\", ".").replace("/", ".");
		return path.replace(".java", "").replace("src.", "");
	}

}
